Many application developers require their applications or “apps” to run across multiple operating systems. Each operating system provider typically provides a Software Development Kit (SDK) allowing applications to be developed only for the provider's specific operating system. Developers have two options:
Option 1: Develop for each target operating system (OS) using each respective OS-specific SDK. The problem with this option is that is can be expensive and time-consuming: each OS-specific SDK environment requires domain knowledge; the SDK environments mandate different programming languages (C++, C#, Objective-C, Java, etc.); each implementation must be separately tested, etc.
Option 2: Develop for multiple target OSs simultaneously by using a “cross-platform” SDK. A cross-platform approach allows developers to maintain a single body of source code, whilst still being able to compile and deploy to multiple target OS platforms. Cross-platform SDKs are generally provided by Independent Software Vendors (ISVs) rather than the OS providers. The number of ISVs providing Option 2 is increasing because Option 1 is becoming more expensive and time-consuming.
Each cross-platform SDK presents the developer with an abstracted Application Programming Interface (API) set (the “OS abstraction API”) allowing a single application source code to target multiple OS environments. The application source code is usually prevented from referencing OS-specific APIs; the application's only interaction with the OS must be through the abstracted APIs.
There are three conventional variations on the cross-platform SDK approach:
Variation A: Virtual Machine (VM). Source code is authored in a language such as JavaScript, Java or C#. The source code is compiled to a “bytecode” instruction set for delivery to a target device. The bytecode is not “machine code” native to any specific CPU.
The target device contains a runtime “interpreter” for the bytecode (this interpreter may itself be bundled and delivered with the app, or it may already be resident on the target device). This interpreter is known as a Virtual Machine (VM). Typically the SDK provider will provide a separate version of the VM for each target OS.
When the application is executed, the bytecode is interpreted by the VM and converted into machine code native to the CPU of the device. This conversion process can happen on-the-fly every time each bytecode instruction is interpreted; or “Just In Time” (JIT) by interpreting a block of instructions, converting to machine code, and caching the resulting code in memory so that it does not need to be converted again within the same execution of the application; or “Ahead Of Time” (AOT) by applying the JIT process to the entire bytecode as soon as the application is launched (this is the most time-consuming and memory-intensive approach).
The Variation A approach requires only one compilation of the source code (to the VM bytecode), and everything else is handled at application execution time by the VM. Examples include J2ME (from Oracle), Flash (from Adobe) and .NET (or the “Common Language Runtime”, from Microsoft).
Variation A provides the purest form of binary portability, but at the expense of runtime performance. Interpreted code is slower than pre-compiled code, and yet conducting the code compilation process on the target device (either JIT or AOT) itself impacts performance.
Variation B: Transcoding, or Code Morphing. Source code can be authored in a variety of languages. Standard compilers such as the CodeSourcery GCC compiler are comprised of stages. Typically one stage (the “front end”) compiles the source code into an intermediary binary code; another stage (the “back end”) then compiles the intermediary binary code into executable code for the target application execution environment, which might be machine code native to a specific CPU, or might be a bytecode for a VM.
The Code Morphing approach typically extracts the intermediary binary code from the first stage of the compilation process, and then decompiles this binary code into a source code target native to an OS-specific SDK. For example, the source code might be authored in Java; the GCC compiler front end would convert this into intermediary binary code; the cross-platform SDK might then extract the binary code and decompile it into Objective-C in a manner suitable for recompilation within the Apple iPhone SDK. The cross-platform SDK would support decompilation into multiple OS-specific source codes, and the developer would then be responsible for compiling these within multiple OS-specific SDKs in order to generate “native” applications for all of the desired targets.
This approach requires multiple separate compilations of the automatically-generated OS-specific source code, and therefore requires the developer to install multiple OS-specific SDKs. Examples include MoSync (from Mobile Sourcery) and Metismo (from Software AG).
Variation B does not require any on-device code interpretation, but the process of decompiling the intermediary compiler binary code, and recompiling within the OS-specific SDK, results in code which is far from optimally-performant. Furthermore, the auto-generation of OS-specific source code from the developer's original source code makes source code management more complex; there is a temptation for the developer to modify the auto-generated source code, and these modifications can be lost if the auto-generation process is repeated. Finally, this approach requires the auto-generated code to be compiled separately within each OS-specific SDK environment. The resultant versions of the application are very different in terms of CPU machine code, and therefore the likelihood of OS-specific bugs is increased.
Variation C: Source Code Compatibility. This is in some ways the simplest approach. The cross-platform SDK presents the developer with a set of programming interfaces that have been implemented separately within each OS-specific SDK. The developer can then simply compile their application source code, combined with the cross-platform SDK implementation, within the OS-specific SDK environment in order to generate an application for the target OS. This approach requires multiple separate compilations of the application source code, and therefore requires the developer to install multiple OS-specific SDKs. However, the main flaw of this approach is that the developer source code can only be compiled within OS-specific SDKs that accept that source code language choice. For example, source code authored in Java could be compiled within Google's Android SDK, but not within Apple's iPhone SDK. Examples include Qt (from Nokia); many developers also create their own in-house solutions using this approach.
Variation C is the best in terms of compiled code performance, as the code compiler provided by each OS-specific SDK can be utilised as intended, with all compiler optimisations applied. However, the source code still needs to be compiled separately within each OS-specific SDK environment, and resultant versions of the application are very different in terms of CPU machine code, with the likelihood of OS-specific bugs being increased. The major downside is that the number of supportable OS platforms is highly restricted, as the developer must make a single choice of source code language, yet currently many of the most popular target OS platforms have OS-specific SDKs that mandate a single and differing source code language choice.
There is a need for a new approach to cross-platform application development that achieves an optimal balance of binary code portability with high runtime performance.
The present invention seeks to provide an improved method of producing executable applications.
The present invention seeks to provide an improved method and system for evaluating executable applications.
A common convenient method of evaluating applications is to run a version of the application on the host development system. Given the configuration of the host development system, this evaluation may be within a processor architecture and operating system that differs from all or most of the target devices. Such an evaluation can be termed a “simulation”. Furthermore, the hardware form factor of the host development system is likely to differ considerably from that of all or most of the target devices; for example, the host development system may receive inputs from a mouse and alphanumeric keyboard, whilst the target devices might receive inputs from a touchscreen and a small number of specific buttons.
The present invention seeks to provide an improved method and arrangement for simulating execution of an executable application.